﻿using Chemistry.Models;
using Chemistry.Tools;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Novacode;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
using System.Windows;

namespace Chemistry.ViewModels
{
    using System.Windows.Threading;
    using System.Diagnostics;

    /// <summary>
    /// 考试中 vm
    /// </summary>
   public class ExamingViewModel:VmBase
    {
        private bool _canTemperatureTrigger;
        private bool _canPressureTrigger;
        private bool _canLeakTriggere;

       private const int TOTAL_MINUTE = 30;//考试时间 （分钟）
       private CancellationTokenSource _cts;
       //private DeExaminee _de_examinee;
       private ConfigModel _configmodel;

       public RelayCommand RollCommand { get; set; }
       //public RelayCommand BackCommand { get; set; }
       public RelayCommand CheckDetailCommand { get; set; }
       public RelayCommand PrintCommand { get; set; }
       public RelayCommand TemperatureAbnormalCommand { get; set; }
       public RelayCommand CheckQuestionCommand { get; set; }
       public RelayCommand PressureAbnormalCommand { get; set; }
       public RelayCommand LeakAbnormalCommand { get; set; }
        #region 属性
       private ImageSource _imageSource;

       public ImageSource ImageSource
       {
           get { return _imageSource; }
           set { _imageSource = value; RaisePropertyChanged("ImageSource"); }
       } 

        private DateTime _remain;

        public DateTime Remain
        {
            get { return _remain; }
            set { _remain = value; RaisePropertyChanged("Remain"); }
        }

        private bool _isover;

        public bool IsOver
        {
            get { return _isover; }
            set { _isover = value; RaisePropertyChanged("IsOver"); }
        }

        private int _score;

        public int Score
        {
            get { return _score; }
            set { _score = value; RaisePropertyChanged("Score"); }
        }

        private string _message;

        public string Message
        {
            get { return _message; }
            set { _message = value; RaisePropertyChanged("Message"); }
        }
        private ExamInfo _examinfo;

        public ExamInfo ExamInfo
        {
            get { return _examinfo; }
            set { _examinfo = value; RaisePropertyChanged("ExamInfo"); }
        }

        private Visibility _buttonVisible;

        public Visibility ButtonVisible
        {
            get { return _buttonVisible; }
            set { _buttonVisible = value; RaisePropertyChanged("ButtonVisible"); }
        }

        private Visibility _canCheckQeustion;

        public Visibility CanCheckQuestion
        {
            get { return _canCheckQeustion; }
            set { _canCheckQeustion = value; RaisePropertyChanged("CanCheckQuestion"); }
        }


        public List<ExaminationPoint> Points { get; set; }
        #endregion



       public ExamingViewModel()
       {
           RollCommand = new RelayCommand(RollExec,()=>ExamInfo!=null&&!IsOver);
           CheckDetailCommand = new RelayCommand(CheckDetailExec, () => IsOver);
           CheckQuestionCommand = new RelayCommand(CheckQuestionExec);
           PrintCommand = new RelayCommand(PrintExec,()=>IsOver);
           TemperatureAbnormalCommand = new RelayCommand(TemperatureAbnormalExec,()=>!IsOver&& _canTemperatureTrigger);
           PressureAbnormalCommand = new RelayCommand(PressureAbnormalExec,()=>!IsOver&&_canPressureTrigger);
           LeakAbnormalCommand = new RelayCommand(LeakAbnormalExec, () => !IsOver&&_canLeakTriggere);
           InitMessage();
       }

   

       #region 命令方法

       private void CheckQuestionExec()
       {
           var temp = Points.Where(i => i.IsChecked).ToList();
           Send(temp, MessageToken.CheckQuestion);
       }

       private void TemperatureAbnormalExec()
       {
           _canTemperatureTrigger = false;
           ExamInfo.WorkFlow.TemperatureAbnormal();
       }
       private void LeakAbnormalExec()
       {
           _canLeakTriggere = false;
           ExamInfo.WorkFlow.LeakageAbnormal();
       }

       private void PressureAbnormalExec()
       {
           _canPressureTrigger = false;
           ExamInfo.WorkFlow.PressureAbnormal();
       }

       private void PrintExec()
       {
           try
           {
               string startUpPath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
               DocX doc = DocX.Load(startUpPath + "print\\new.docx");
               doc.ReplaceText("$flowname$", _configmodel.WorkflowChineseName);
               doc.ReplaceText("$company$", "");
               doc.ReplaceText("$index$", (Global.PrintIndex++).ToString());
               doc.ReplaceText("$number$", ExamInfo.Examinee.TicketId);
               doc.ReplaceText("$name$", ExamInfo.Name);

               doc.ReplaceText("$step$", ExamInfo.WorkFlow.Content);
               doc.ReplaceText("$score$", (ExamInfo.Score * 0.5).ToString());
               string path = _configmodel.PrintPath ?? "C:\\print";
               string filename = string.Format("{0}_{1}.doc", (DateTime.Now.ToString("yyyyMMddhhmmss")), ExamInfo.Examinee.Name);
               var savepath = _configmodel.PrintPath + "\\" + filename;
               doc.SaveAs(savepath);
               doc.Dispose();
               Process.Start(savepath);
               Message = "打印完成";
               //MessageBox.Show("打印完成", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
           }
           catch (Exception ex)
           {
               LogTool.WriteErrorLog(ex);
           }
       }

       private void CheckDetailExec()
       {
           Send<string>(ExamInfo.WorkFlow.Content, MessageToken.CheckDetail);
       }

       private void RollExec()
       { 
           if (MessageBox.Show("确定要交卷吗？", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Question)
               == MessageBoxResult.OK)
           {
               Roll();
           }
       }
       private void Roll()
       {
           try
           {
               //Console.WriteLine("Roll:     " + Thread.CurrentThread.ManagedThreadId);
              // IsOver = true;
               _cts.Cancel();
               ExamInfo.WorkFlow.Over();
           }
           catch (Exception e)
           {
               ExamInfo.Permission.CanCommit = true;
               this.Message = "异常： " + e.Message;
               LogTool.WriteErrorLog(e.StackTrace);
               LogTool.WriteErrorLog(e.Message, e);
           }
       }
        private bool CanCheckDetail()
        {
            bool i = IsOver;
            return i;
        }
       #endregion

       #region 初始化
       private void InitMessage()
       {
           Register<ExamInfoMessage>(
               this,
               MessageToken.ShowExamingWindow,
               (i) =>
                   {
                       this.ExamInfo = i.ExamInfo;
                       if (i.IsFirstShow)
                       {
                           InitFiled();
                           InitImage();
                           InitState();
                           this.ButtonVisible = i.IsStep ? Visibility.Collapsed : Visibility.Visible;
                           this.CanCheckQuestion = i.IsStep ? Visibility.Visible : Visibility.Collapsed;
                           _configmodel = Tool.GetConfig();
                           Points = i.Points;
                           //var guid = ExamInfo.Examinee.Guid.ToString();
                           //_de_examinee = DeExaminee.FindOne(i => i.Guid == guid);
                           ExamInfo.WorkFlow.FinishHandler += WorkFlow_FinishHandler;
                           ExamInfo.WorkFlow.MessageHandler += WorkFlow_MessageHandler;
                       }

                   });

           Register<object>(this, MessageToken.StopExaming,
                (i) =>
                {
                    _cts.Cancel();
                });
       }

       private void InitFiled()
       {
           IsOver = false;
           Message = string.Empty;
           _canLeakTriggere = true;
           _canPressureTrigger = true;
           _canTemperatureTrigger = true;
       }

       void WorkFlow_MessageHandler(string message)
       {
           Message = !string.IsNullOrEmpty(message) ? string.Format("{0}\t{1}", message, Date.Now.ToString("HH:mm:ss")) : "";
       }

       async void WorkFlow_FinishHandler()
       {
           Console.WriteLine("WorkFlow_FinishHandler:     " + Thread.CurrentThread.ManagedThreadId);
           ExamInfo.ExamState = ExamState.考试完成;
           ExamInfo.Permission.CanBeginExam = false;
           ExamInfo.Permission.CanInput = true;
           ExamInfo.Permission.CanCheckDetail = true;

           int score = ExamInfo.WorkFlow.Score;
           ExamInfo.Score = score;
           this.Score = score;
           IsOver = true;

           bool issuccess = true;
           if (Global.RunModel == RunModel.考试模式)
           {
               issuccess = await UploadScore(ExamInfo.Examinee);
           }
           
           //AddToLocal();

           if (!issuccess)
           {
               ExamInfo.Permission.CanCommit = true;
           }
           else
           {
               Message = string.Format("{0}\t{1}", "上传成绩完成", Date.Now.ToString("HH:mm:ss"));
               Send<bool>(false, MessageToken.IsExaming);
               string info = string.Format("{0} 交卷,得分:{1},详情：{2}", ExamInfo.Name, Score, ExamInfo.WorkFlow.Content);
               ServerLogTool.UploadLog(info, EventType.Information);
           }
       }

        private async void UploadM()
        {
            Console.WriteLine("UPloadM:     " + Thread.CurrentThread.ManagedThreadId);
           
            bool issuccess = await UploadScore(ExamInfo.Examinee);
            //AddToLocal();

            if (!issuccess)
            {
                ExamInfo.Permission.CanCommit = true;
            }
            else
            {

                 IsOver = true;
                Send<bool>(false, MessageToken.IsExaming);
                string info = string.Format("{0} 交卷,得分:{1},详情：{2}", ExamInfo.Name, Score, ExamInfo.WorkFlow.Content);
                ServerLogTool.UploadLog(info, EventType.Information);
            }
        }

       private void AddToLocal()
       {
           //try
           //{
           //    var currentExaminfo = ExamInfo.Examinee;
           //    DeExaminee examinee = new DeExaminee()
           //    {
           //        CardId = currentExaminfo.CardId,
           //        Content = ExamInfo.WorkFlow.Content,
           //        ExamDate = ExamInfo.LoginDate,
           //        FlowName = _configmodel.WorkflowChineseName,
           //        Score = this.Score,
           //        Name = currentExaminfo.Name
           //    };
           //    examinee.Save();
           //}
           //catch (Exception ex)
           //{
           //    LogTool.WriteErrorLog(ex);
           //}

       }

       private void InitState()
       {
           _cts = new CancellationTokenSource();
           DateTime endtime = ExamInfo.LoginDate.Value.AddMinutes(TOTAL_MINUTE);
           Task t = new Task(() =>
           {
               while (!_cts.IsCancellationRequested)
               {
                   var remain = (endtime - DateTime.Now).TotalSeconds;

                   if (remain > 0)
                   {
                       var minute = (int)remain / 60;
                       var second = (int)remain % 60;
                       Remain = new DateTime(2014, 1, 1, 1, minute, second);
                       Send<bool>(true, MessageToken.IsExaming);
                   }
                   else
                   {
                       _cts.Cancel();
                       if (ExamInfo.ExamState == ExamState.考试中)
                       {
                           Roll();
                       }
                   }
               }
           });
           t.Start();
       }



       private void InitImage()
       {
           if (ExamInfo.Examinee.Pictrue != null)
           {
               ImageBrush brush = new ImageBrush();
               ImageSourceConverter converter = new ImageSourceConverter();
               this.ImageSource = (ImageSource)converter.ConvertFrom(ExamInfo.Examinee.Pictrue);
           }
           else
           {
               this.ImageSource = new BitmapImage(new Uri(@"\Images\nophoto.jpg", UriKind.Relative));
           }
       } 
       #endregion

       #region 异步方法

       async Task<bool> UploadScore(Examinee examinee)
       {
           bool issuccess = false;
           var data = new ScoreData()
           {
               session = HttpBasePrimary.Session,
               nr = examinee.TicketId,
               items = new List<Score>()
                {
                    new Score() {name = "hg_", value = Score}
                }
           };
           string tipmessage = string.Empty;
           try
           {
               var rdata = await HttpBasePrimary.PostAsJsonAsync<ResultData>("Score", data);
               string logMsg = string.Format("考生{0}上传分数，返回值{1}", examinee.CardId, rdata.status);
               LogTool.WriteInfoLog(logMsg);

               switch (rdata.status)
               {
                   case 0:
                       tipmessage = "上传成绩完成";
                       issuccess = true;
                       break;
                   case -1:
                       tipmessage = "身份验证失败，请尝试重录系统";
                       break;
                   case -2:
                       tipmessage = "上传成绩失败：参数异常";
                       break;
                   case -3:
                       tipmessage = "上传成绩失败：服务器内部错误，请联系管理员";
                       break;
                   case 2:
                       tipmessage = "未知的分数项代码";
                       break;
               }
           }
           catch (Exception ex)
           {
               tipmessage = "上传过程中遇到错误，请确认网络畅通";
               LogTool.WriteErrorLog(ex.Message, ex);
           }
           Message = string.Format("{0}\t{1}", tipmessage, Date.Now.ToString("HH:mm:ss"));
           return issuccess;
       }
       #endregion
    }
}
